// @Author: cyl
// @File: slice_memory内存泄漏.go
// @Time: 2023/07/18 22:31:08
package main

import (
	"fmt"
)

const (
	TOTAL = 1 << 20
	begin = 2
	end   = 7
)

func return_sub_slice1() []int {
	parent := make([]int, TOTAL) // parent切片持有一个1M的int数组，占有内存8M
	child := parent[begin:end]   // 只要child没有被GC回收，长度为1M的int数组就一直得不到释放
	return child                 // child仍然持有底层的那个大数组
}

func return_sub_slice2() []int {
	parent := make([]int, TOTAL)
	length := end - begin          // 先计算出child切片的长度
	child := make([]int, length)   // 根据chile切片长度单独申请一个内存
	for i := begin; i < end; i++ { // 将child的值逐个拷贝到parent中
		child[i-begin] = parent[i]
	}
	return child
}

func use_sub_slice() {
	s1 := return_sub_slice1()
	fmt.Printf("s1 -> init len: %d, cap: %d, TOTAL: %d\n", len(s1), cap(s1), TOTAL)
	for i := 0; i < 5; i++ {
		s1 = append(s1, 9)
		fmt.Printf("s1 -> update len: %d, cap: %d\n", len(s1), cap(s1))
	}

	fmt.Println("========================================")

	s2 := return_sub_slice2()
	fmt.Printf("s2 -> init len: %d, cap: %d, TOTAL: %d\n", len(s2), cap(s2), TOTAL)
	for i := 0; i < 5; i++ {
		s1 = append(s2, 9)
		fmt.Printf("s2 -> update len: %d, cap: %d\n", len(s2), cap(s2))
	}
}

func main2() {
	use_sub_slice()
	/** 输出:
	s1 -> init len: 5, cap: 1048574, TOTAL: 1048576
	s1 -> update len: 6, cap: 1048574
	s1 -> update len: 7, cap: 1048574
	s1 -> update len: 8, cap: 1048574
	s1 -> update len: 9, cap: 1048574
	s1 -> update len: 10, cap: 1048574
	========================================
	s2 -> init len: 5, cap: 5, TOTAL: 1048576
	s2 -> update len: 5, cap: 5
	s2 -> update len: 5, cap: 5
	s2 -> update len: 5, cap: 5
	s2 -> update len: 5, cap: 5
	*/
}
